package cn.iocoder.yudao.module.promotion.groupon.service.app;

import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.business.basic.pojo.dto.SimpleQueryDTO;
import cn.iocoder.yudao.framework.business.basic.service.CrudService;
import cn.iocoder.yudao.framework.business.basic.service.impl.BaseService;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.exception.Assertions;
import cn.iocoder.yudao.module.api.infrastructure.config.ConfigApiV2;
import cn.iocoder.yudao.module.api.product.sku.ProductSkuApi;
import cn.iocoder.yudao.module.api.product.sku.dto.ProductSkuRespDTO;
import cn.iocoder.yudao.module.api.product.spu.ProductSpuApi;
import cn.iocoder.yudao.module.api.product.spu.dto.ProductSpuRespDTO;
import cn.iocoder.yudao.module.api.product.spu.enums.ProductSpuStatusEnum;
import cn.iocoder.yudao.module.api.shop.info.ShopInfoApi;
import cn.iocoder.yudao.module.api.shop.info.dto.ShopInfoDTO;
import cn.iocoder.yudao.module.promotion.groupon.convert.GrouponProductConvert;
import cn.iocoder.yudao.module.promotion.groupon.dao.GrouponPackageMapper;
import cn.iocoder.yudao.module.promotion.groupon.dao.GrouponProductMapper;
import cn.iocoder.yudao.module.promotion.groupon.pojo.po.GrouponPackage;
import cn.iocoder.yudao.module.promotion.groupon.pojo.po.GrouponProduct;
import cn.iocoder.yudao.module.promotion.groupon.pojo.vo.AppGrouponProductRespVO;
import cn.iocoder.yudao.module.promotion.groupon.pojo.vo.GrouponProductSaveDTO;
import jakarta.annotation.Nullable;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.util.List;
import java.util.Set;

import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserLastShopId;

/**
 * <pre>
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 *  这里是文件说明
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 * </pre>
 *
 * @author 山野羡民（1032694760@qq.com）
 * @since 2025/01/13
 */
@Slf4j
@Service
@Validated
public class AppGrouponProductServiceImpl extends BaseService<GrouponProduct, AppGrouponProductRespVO, SimpleQueryDTO> implements AppGrouponProductService, CrudService<GrouponProduct, AppGrouponProductRespVO, GrouponProductSaveDTO, SimpleQueryDTO> {
    @Resource
    private GrouponProductMapper grouponProductMapper;
    @Resource
    private GrouponPackageMapper grouponPackageMapper;

    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private ShopInfoApi shopInfoApi;
    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private ProductSkuApi productSkuApi;
    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private ProductSpuApi productSpuApi;
    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private ConfigApiV2 configApiV2;

    @Override
    public GrouponProductMapper getInjectedMapper() {
        return grouponProductMapper;
    }

    @Override
    public GrouponProduct convertToEntity(GrouponProductSaveDTO param) {
        return GrouponProductConvert.INSTANCE.convert(param);
    }

    @Override
    public AppGrouponProductRespVO convertToViewObject(GrouponProduct entity) {
        AppGrouponProductRespVO respVO = GrouponProductConvert.INSTANCE.convert(entity);
        respVO.setDeductUnitPrice(configApiV2);
        return respVO;
    }

    @Override
    public void beforeCreate(GrouponProduct entity, @Nullable Long userId) {
        ShopInfoDTO shopInfo = shopInfoApi.getShopInfo(getLoginUserLastShopId());
        Assertions.isTrue(shopInfo != null, "当前用户没有店铺");
        Assertions.isTrue(CommonStatusEnum.isEnable(shopInfo.getEnabled()), "店铺已被封禁：" + shopInfo.getName());
        entity.setShopId(shopInfo.getId());
        if (entity.getSkuId() != null && entity.getSkuId() > 0) {
            ProductSkuRespDTO skuRespDTO = productSkuApi.validateSku(entity.getSkuId());
            Assertions.equals(skuRespDTO.getShopId(), shopInfo.getId(), "选择的产品不是自己店铺的：" + shopInfo.getName());
            entity.setSkuId(skuRespDTO.getId());
            ProductSpuRespDTO spuRespDTO = productSpuApi.validateSpu(skuRespDTO.getSpuId());
            entity.setSpuId(spuRespDTO.getId());
            entity.setName((spuRespDTO.getName() + " " + skuRespDTO.getPropertiesValue()).trim());
            Assertions.isTrue(ProductSpuStatusEnum.isEnable(spuRespDTO.getStatus()), "选择套餐产品不是上架状态：" + spuRespDTO.getName());
            if (StrUtil.isBlank(skuRespDTO.getPicUrl())) {
                entity.setPicUrl(spuRespDTO.getPicUrl());
            } else {
                entity.setPicUrl(skuRespDTO.getPicUrl());
            }
            entity.setCostPrice(skuRespDTO.getCostPrice());
            entity.setOriginPrice(skuRespDTO.getPrice());
            entity.setUnit(spuRespDTO.getUnitName());
        }
        Assertions.isTrue(entity.getPrice() >= entity.getCostPrice(), "套卖销售价不能小于成本价");
        Assertions.isTrue(entity.getPrice() <= entity.getOriginPrice(), "套卖销售价不能大于单卖销售价");
        Assertions.isTrue(entity.getVipPrice() <= entity.getPrice(), "套卖会员价不能大于套卖销售价");
    }

    @Override
    public void afterCreate(GrouponProduct entity) {
        updatePrice(entity.getPackageId());
    }

    @Override
    public void beforeUpdate(GrouponProduct entity) {
        Assertions.isTrue(entity.getPrice() >= entity.getCostPrice(), "套卖销售价不能小于成本价");
        Assertions.isTrue(entity.getPrice() <= entity.getOriginPrice(), "套卖销售价不能大于单卖销售价");
        Assertions.isTrue(entity.getVipPrice() <= entity.getPrice(), "套卖会员价不能大于套卖销售价");
    }

    @Override
    public void afterUpdate(GrouponProduct entity) {
        updatePrice(entity.getPackageId());
    }

    @Override
    public void afterDelete(GrouponProduct entity) {
        updatePrice(entity.getPackageId());
    }

    private void updatePrice(Long packageId) {
        List<GrouponProduct> list = grouponProductMapper.selectListByPackageId(packageId);
        int costPrice = 0;
        int originPrice = 0;
        int price = 0;
        int vipPrice = 0;
        for (GrouponProduct item : list) {
            costPrice += item.getCostPrice() * item.getCount();
            originPrice += item.getOriginPrice() * item.getCount();
            price += item.getPrice() * item.getCount();
            vipPrice += item.getVipPrice() * item.getCount();
        }
        GrouponPackage updateObj = new GrouponPackage();
        updateObj.setId(packageId);
        updateObj.setCostPrice(costPrice);
        updateObj.setOriginPrice(originPrice);
        updateObj.setPrice(price);
        updateObj.setVipPrice(vipPrice);
        grouponPackageMapper.updateById(updateObj);
    }

    @Override
    public List<AppGrouponProductRespVO> getListByPackageId(Long packageId) {
        List<GrouponProduct> list = grouponProductMapper.selectListByPackageId(packageId);
        log.trace("getListByPackageId DeductUnitPrice before:{}", list);
        List<AppGrouponProductRespVO> respVOS = GrouponProductConvert.INSTANCE.convertList(list);
        respVOS.forEach(it -> it.setDeductUnitPrice(configApiV2));
        log.trace("getListByPackageId DeductUnitPrice after:{}", respVOS);
        return respVOS;
    }

    @Override
    public List<AppGrouponProductRespVO> getListByPackageIds(Set<Long> packageIds) {
        List<GrouponProduct> list = grouponProductMapper.selectListByPackageIds(packageIds);
        List<AppGrouponProductRespVO> respVOS = GrouponProductConvert.INSTANCE.convertList(list);
        respVOS.forEach(it -> it.setDeductUnitPrice(configApiV2));
        return respVOS;
    }

}
